/**
 * 
 */
package org.melord.cap;

import org.eclipse.swt.widgets.Shell;

/**
 * @author melord
 * 
 */
public class ControlWraper extends Global {
	private Control control;
	private boolean startWarn = false;
	private boolean stopWarn = false;
	public Runnable alertThread;
	public Runnable countDownThread;
	public long currentTime = System.currentTimeMillis();

	public ControlWraper(Control control) {
		this.control = control;
		init();
	}

	private void init() {
		String text = control.getText();
		if (empty(text)) {
			if (control.getGroup() != null) {
				text = control.getGroup().getText();
				if (empty(text)) {
					text = control.getGlobal().getText();
				}
			} else {
				text = control.getGlobal().getText();
			}
		}

		if (empty(text)) {
			text = "null";
		}
		this.text = text;
		this.text = this.text.replaceAll("\\$\\{context\\}", control
				.getContext());

		// init url prefix
		text = control.getUrlPrefix();
		if (empty(text)) {
			if (control.getGroup() != null) {
				text = control.getGroup().getUrlPrefix();
				if (empty(text)) {
					text = control.getGlobal().getUrlPrefix();
				}
			} else {
				text = control.getGlobal().getUrlPrefix();
			}
		}

		if (empty(text)) {
			text = "null";
		}
		this.urlPrefix = text;

		// init time;
		long t = control.getTime();
		if (t == 0) {
			if (control.getGroup() != null) {
				t = control.getTime();
				if (t == 0) {
					t = control.getGlobal().getTime();
				}
			} else {
				t = control.getGlobal().getTime();
			}
		}

		if (Cfg.getInstance().getTimeUnit() == Cfg.TIME_UNIT_MIN) {
			t = t * 60;
		}

		this.time = t * 1000;

		// init warn begin;
		t = control.getWarnBegin();
		if (t == 0) {
			if (control.getGroup() != null) {
				t = control.getWarnBegin();
				if (t == 0) {
					t = control.getGlobal().getWarnBegin();
				}
			} else {
				t = control.getGlobal().getWarnBegin();
			}
		}

		if (Cfg.getInstance().getTimeUnit() == Cfg.TIME_UNIT_MIN) {
			t = t * 60;
		}

		this.warnBegin = t * 1000;
		// int warn interval
		t = control.getWarnInterval();
		if (t == 0) {
			if (control.getGroup() != null) {
				t = control.getWarnInterval();
				if (t == 0) {
					t = control.getGlobal().getWarnInterval();
				}
			} else {
				t = control.getGlobal().getWarnInterval();
			}
		}

		if (Cfg.getInstance().getTimeUnit() == Cfg.TIME_UNIT_MIN) {
			t = t * 60;
		}

		this.warnInterval = t * 1000;
	}

	public boolean isStartWarn() {
		return startWarn;
	}

	public void setStartWarn(boolean startWarn) {
		this.startWarn = startWarn;
	}

	public boolean isStopWarn() {
		return stopWarn;
	}

	public void setStopWarn(boolean stopWarn) {
		this.stopWarn = stopWarn;
	}

	public long getRemainTime(long currentTime) {
		return getTime() - (System.currentTimeMillis() - currentTime);
	}

	public Control getControl() {
		return control;
	}

	private boolean empty(String str) {
		if (str == null || str.isEmpty()) {
			return true;
		}
		return false;
	}

	public void startAlert(final Shell shell) {
		if (shell.isDisposed()) {
			System.out.println("shell disposed!");
			return;
		}
		final int duration = (int) getWarnInterval(); //
		alertThread = new Runnable() {
			@Override
			public void run() {
				if (shell.isDisposed()) {
					return;
				}
				playAlert();
				if (!isStopWarn()) {
					shell.getDisplay().timerExec(duration, this);
				}
			}

			private void playAlert() {
				shell.getDisplay().beep();
			}
		};
		shell.getDisplay().asyncExec(alertThread);
	}

	public void startCountDown(final Shell shell,
			final CountDownListener listener) {
		final int duration = 1000;
		countDownThread = new Runnable() {
			@Override
			public void run() {
				if (shell.isDisposed()) {
					return;
				}
				long diff = getRemainTime(currentTime);

				if (listener != null) {
					listener.update(ControlWraper.this, diff);
				}

				if (diff < getWarnBegin() && !isStartWarn()) {
					setStartWarn(true);
					startAlert(shell);
				}
				if (diff > 0) {
					shell.getDisplay().timerExec(duration, this);
				} else {
					// setStopWarn(true);
					// if (alertThread != null) {
					// System.out.println("stop count down");
					// shell.getDisplay().timerExec(-1, alertThread);
					// }
					// if (listener != null) {
					// listener.stop(ControlWraper.this);
					// }
				}
			}
		};
		shell.getDisplay().asyncExec(countDownThread);
	}

	public void stop(final Shell shell) {
		if (shell.isDisposed()) {
			return;
		}
		if (countDownThread != null) {
			shell.getDisplay().timerExec(-1, countDownThread);
		}
		if (alertThread != null) {
			shell.getDisplay().timerExec(-1, alertThread);
		}
	}

	public static interface CountDownListener {
		void update(ControlWraper ctrl, long remain);

		void stop(ControlWraper ctrl);
	}

}
